// SMTPSocket.cpp: implementation of the CSMTPSocket class.
//
//////////////////////////////////////////////////////////////////////

#include "SMTPSocket.h"
#include "MyParse.h"
#include "Sockets/Utility.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSMTPSocket::CSMTPSocket(ISocketHandler& h)
:TcpSocket(h)
{
	SetLineProtocol();
	m_bMailSent = FALSE;
	m_pMail = NULL;
}

CSMTPSocket::~CSMTPSocket()
{

}

void CSMTPSocket::SetSmtpHost(const std::string& host)
{
	m_strSmtpHost = host;
}

void CSMTPSocket::SetSmtpPort(unsigned int port)
{
	m_nSmtpPort = port;
}

void CSMTPSocket::SetSmtpUsername(const std::string& usr)
{
	m_strSmtpUsr = usr;
}

void CSMTPSocket::SetSmtpPassword(const std::string& pwd)
{
	m_strSmtpPwd = pwd;
}

void CSMTPSocket::SendMail(CEmail * pMail)
{
	m_pMail = pMail;
}
	
bool CSMTPSocket::IsMailSent()
{
	return m_bMailSent;
}

bool CSMTPSocket::Connect()
{
	return Open(m_strSmtpHost, m_nSmtpPort);
}

void CSMTPSocket::OnConnect()
{
	if(NULL == m_pMail)
		SetCloseAndDelete();
}

void CSMTPSocket::OnConnectFailed()
{

}

void CSMTPSocket::OnLine(const std::string& line)
{
	MyParse pa(line);

	std::string code(pa.getword());

	if ("220" == code)
	{
		Send("HELO " + m_strSmtpHost + "\r\n");
		m_strLastCmd = "HELO";
	} 
	else if ("250" == code)
	{
		if ("HELO" == m_strLastCmd)
		{
			Send("AUTH LOGIN\r\n");
			m_strLastCmd = "AUTH";
		} 
		else if("MAIL" == m_strLastCmd)
		{
			for (CEmail::To to = m_pMail->GetFirstTo(); !to.IsEmpty();
				to = m_pMail->GetNextTo()
			)
			{
				Send("RCPT TO: <" + to.addr + ">\r\n");
				m_strLastCmd = "RCPT";
			}

			if ("RCPT" != m_strLastCmd)
			{
				SetCloseAndDelete();
				return;
			}	
		}
		else if("RCPT" == m_strLastCmd)
		{
			Send("DATA\r\n");
			m_strLastCmd = "DATA";
		}
		else if("DATA" == m_strLastCmd)
		{
			m_bMailSent = true;
			Send("QUIT\r\n");
			m_strLastCmd = "QUIT";
		}
	} 
	else if ("334" == code)
	{
		std::string cmd = pa.getword();
		if ("VXNlcm5hbWU6" == cmd)
		{
			Send(Utility::base64(m_strSmtpUsr) + "\r\n");
			m_strLastCmd = "USR";
		} 
		else if ("UGFzc3dvcmQ6" == cmd)
		{
			Send(Utility::base64(m_strSmtpPwd) + "\r\n");
			m_strLastCmd = "PWD";
		}
	} 
	else if ("235" == code)
	{
		if(NULL == m_pMail)
		{
			SetCloseAndDelete();
			return;
		}

		Send("MAIL FROM: <" + m_pMail->GetFrom().addr + ">\r\n");
		m_strLastCmd = "MAIL";
	}
	else if ("354" == code)
	{
		if(NULL == m_pMail)
		{
			SetCloseAndDelete();
			return;
		}

		std::string data;
		m_pMail->GetData(data);

		Send(data);

		Send("\r\n.\r\n");
	}
	else if ("221" == code)
	{
		if ("QUIT" == m_strLastCmd)
		{
			SetCloseAndDelete();
			return;
		} 
		else
		{
		}
	}
	else
	{
		SetCloseAndDelete();
	}
}